using SerialPortCommunicationProject.Tools;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.IO.Ports;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using Tool;

namespace SerialPortCommunicationProject
{

    public enum FormatType
    {
        Ascii = 0,
        Hex = 1
    }
   
    /// <summary>
    /// App.xaml 的交互逻辑
    /// </summary>
    public partial class App : Application
    {
        // data
        private static ObservableCollection<Device> lstDevices = new ObservableCollection<Device>();
        public static ObservableCollection<Device> LstDevices { get => lstDevices; set => lstDevices = value; }
        public static Device CurrentDevice { get => currentDevice; set => currentDevice = value; }
        public static ICommunication Comm { get => comm; set => comm = value; }
        public static Command CurrentCommand { get => currentCommand; set => currentCommand = value; }

        private static Device currentDevice;

        private static Command currentCommand;

        private static ICommunication comm;

        /// <summary>
        /// 获取当前应用版本号
        /// </summary>
        /// <returns></returns>
        public static Version GetEdition()
        {
            return System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
        }

        public static List<string> GetServerIpAddresses()
        {
            List<string> ipv4Addresses = new List<string>() {
                    "127.0.0.1",
                    "0.0.0.0"
                };
            IPAddress[] hostAddresses = Dns.GetHostAddresses(Dns.GetHostName());
            foreach (IPAddress ipAddr in hostAddresses)
            {
                if (ipAddr.AddressFamily == AddressFamily.InterNetwork)
                {
                    string s = (new IPAddress(ipAddr.GetAddressBytes())).ToString();
                    ipv4Addresses.Insert(0, s);
                }
            }
            return ipv4Addresses;
        }
        public static Parity StringToParity(string value)
        {
            Parity parity = Parity.None;
            switch (value)
            {
                case "0": break;
                case "1": parity = Parity.Odd; break;
                case "2": parity = Parity.Even; break;
                case "3": parity = Parity.Mark; break;
                case "4": parity = Parity.Space; break;
            }
            return parity;
        }
        public static string ParityToString(Parity parity)
        {
            string value = "None";
            switch (parity)
            {
                case Parity.None: break;
                case Parity.Odd:
                    value = "Odd";
                    break;
                case Parity.Even:
                    value = "Even";
                    break;
                case Parity.Mark:
                    value = "Mark";
                    break;
                case Parity.Space:
                    value = "Space";
                    break;
            }
            return value;
        }
        public static StopBits StringToStopBits(string value)
        {
            StopBits stopBits = StopBits.One;
            switch (value)
            {
                case "1": break;
                case "2": stopBits = StopBits.Two; break;
                case "1.5": stopBits = StopBits.OnePointFive; break;
            }
            return stopBits;
        }

        public static string StopBitsToString(StopBits value)
        {
            string result = "1";
            switch (value)
            {
                case StopBits.One: break;
                case StopBits.Two: result = "2"; break;
                case StopBits.OnePointFive: result = "1.5"; break;
            }
            return result;
        }

        public static string  IsServerToString(bool isServer)
        {
            return isServer ? "TCP Server" : "TCP Client";
        }
        public static bool StringToIsServer(string value)
        {
            if(value.Equals("TCP Server"))
            {
                return true;
            }else
            {
                return false;
            }
        }

        public static void Insert(int index,Device d)
        {
            lstDevices.Insert(index, d);
        }

        public static void RemoveAt(int index)
        {
            lstDevices.RemoveAt(index);
        }

        public static string PortName;
        public static FormatType StringToFormat(string stringType)
        {
            FormatType type = FormatType.Ascii;
            switch (stringType)
            {
                case "ASCII":
                    break;
                case "HEX":
                    type = FormatType.Hex;
                    break;
            }
            return type;
        }
        public static void FormatCommandCode(string commandCode, TextBox textBox, FormatType type)
        {
            switch (type)
            {
                case FormatType.Ascii:
                    break;
                case FormatType.Hex:
                    commandCode = commandCode.Replace(" ", string.Empty);
                    if (commandCode != string.Empty)
                    {
                        commandCode = InteractiveTool.FormatHexJoint(commandCode, out bool error, commandCode.Length % 2 + commandCode.Length);//格式化输入Hex字符串
                        if (error)
                        {
                            MessageBox.Show("参数设置错误");
                            return;
                        }
                    }
                    textBox.Text = commandCode;//更新格式化后的输入框字符串
                    break;
            }
        }
        /// <summary>
        /// 解析常用反义
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        public static string AnalyseEscapeCh(string text)
        {
            string[] oldStr = { "\\b", "\\\\", "\\n", "\\r", "\\a", "\\f", "\\t", "\\v", "\\'" };
            string[] newStr = { "\b", "\\", "\n", "\r", "\a", "\f", "\t", "\v", "\'" };
            for (int i = 0; (oldStr.Length == newStr.Length) && i < oldStr.Length; i++)
            {
                text = text.Replace(oldStr[i], newStr[i]);
            }
            return text;
        }
        public static void SaveMessageBox(Func<bool> func, CancelEventArgs e,string text)
        {
            MessageBoxResult result = MessageBox.Show(text, "询问", MessageBoxButton.YesNo, MessageBoxImage.Question);
            if (result == MessageBoxResult.Yes)
            {
                bool flag = func.Invoke();
                if (!flag)
                {
                    MessageBox.Show("检测到名称重复！不允许创建！");
                }
                e.Cancel = !flag;
            }
            else
            {
                e.Cancel = false;
            }
        }

        public static void ClickItem(ListBox listBox,Window ownerWindow, Window newWindow, Action add = null, Action show = null)
        {
            if (listBox.SelectedIndex < 0)
            {
                return;
            }
            if (listBox.SelectedIndex == listBox.Items.Count - 1)
            {
                if (show != null)
                {
                    show.Invoke();
                }
                if (ownerWindow == null)
                {
                    return;
                }
                newWindow = new NewDeviceWindow();
                newWindow.Owner = ownerWindow;//set owner window
                newWindow.ShowDialog();
                if (add != null)
                {
                    add.Invoke();
                }
            }
        }
        public static string CommunicationModeToString(CommunicationModeEnum mode)
        {
            string result = "";
            if (mode == CommunicationModeEnum.SerialPort)
            {
                result = "串口";
            }
            else if(mode==CommunicationModeEnum.SocketTcp)
            {
                result = "Socket(TCP)";
            }
            return result;
        }

        public static CommunicationModeEnum StringToCommunicationMode(string name)
        {
            CommunicationModeEnum result = CommunicationModeEnum.SerialPort;
            if (name == "串口")
            {
                result = CommunicationModeEnum.SerialPort;
            }
            else if (name == "Socket(TCP)")
            {
                result = CommunicationModeEnum.SocketTcp;
            }
            return result;
        }
    }
}
